package com.eastfair.venuebooking.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.constant.BusinessInnerMsgTemplate;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.context.StaticContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.messagecenter.dto.SmsSendDTO;
import com.eastfair.messagecenter.enumeration.ChannelType;
import com.eastfair.messagecenter.model.SmsContentModel;
import com.eastfair.messagecenter.util.SendMsgUtil;
import com.eastfair.projectcore.enumeration.MenuAffiliationEnum;
import com.eastfair.venuebooking.dao.FollowPlanMapper;
import com.eastfair.venuebooking.dto.FollowPlanDTO;
import com.eastfair.venuebooking.entity.*;
import com.eastfair.venuebooking.enums.FollowPlanSubjectType;
import com.eastfair.venuebooking.enums.FollowRemindTypeEnum;
import com.eastfair.venuebooking.enums.FollowRemindWayEnum;
import com.eastfair.venuebooking.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 业务实现类
 * 跟进计划表
 * </p>
 *
 * @author linan
 * @date 2022-06-08
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class FollowPlanServiceImpl extends SuperServiceImpl<FollowPlanMapper, FollowPlan> implements FollowPlanService {

    @Resource
    private VenueBookingMsgService venueBookingMsgService;

    @Resource
    private VenueBookingUserAccountService venueBookingUserAccountService;

    @Resource
    private CustomerMainService customerMainService;

    @Resource
    private SaleClueService saleClueService;

    @Resource
    private BusinessOpportunityService businessOpportunityService;

    @Resource
    private ContractManageService contractManageService;

    @Resource(name = "threadPoolTaskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private SendMsgUtil sendMsgUtil;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<FollowPlan> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(FollowPlan model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveFollowPlan(FollowPlanDTO followPlanDTO) {
        log.info("saveFollowPlan - 保存跟进计划, followPlanDTO={}", followPlanDTO);
        FollowPlan followPlan = BeanUtil.toBean(followPlanDTO, FollowPlan.class);
        String followRemindType = followPlan.getFollowRemindType();
        LocalDateTime planFollowDate = followPlan.getPlanFollowDate();
        if (StrUtil.isNotBlank(followRemindType) && planFollowDate != null) {
            LocalDateTime followRemindTime = getFollowRemindTime(followRemindType, planFollowDate);
            followPlan.setFollowRemindTime(followRemindTime);
        }
        save(followPlan);
        // 发送消息
        String followRemindWay = followPlan.getFollowRemindWay();
        // 无需发送
        if (StrUtil.isBlank(followRemindWay)) {
            return true;
        }
        String[] followRemindWayArray = followRemindWay.split(",");
        for (String followRemindWayString: followRemindWayArray) {
            // 发送站内信
            if (FollowRemindWayEnum.SYS_MESSAGE.getCode().equals(followRemindWayString)) {
                asyncSendRemindInnerMsg(followPlan);
            }
            // 发送短信
            if (FollowRemindWayEnum.SHORT_MESSAGE.getCode().equals(followRemindWayString)) {
                asyncSendRemindSmsMsg(followPlan);
            }
        }
        return true;
    }

    /**
     * 通过提醒方式和计划跟进时间得到提醒时间
     *
     * @param followRemindType 提醒方式
     * @param planFollowDate   计划跟进时间
     * @return 提醒时间
     */
    private static LocalDateTime getFollowRemindTime(String followRemindType, LocalDateTime planFollowDate) {
        LocalDateTime followRemindTime = null;
        if (FollowRemindTypeEnum.ON_TIME.getCode().equals(followRemindType)) {
            followRemindTime = planFollowDate;
        } else if (FollowRemindTypeEnum.FIVE_MINUTES_EARLY.getCode().equals(followRemindType)) {
            followRemindTime = planFollowDate.minusMinutes(5);
        } else if (FollowRemindTypeEnum.FIFTEEN_MINUTES_EARLY.getCode().equals(followRemindType)) {
            followRemindTime = planFollowDate.minusMinutes(15);
        } else if (FollowRemindTypeEnum.THIRTY_MINUTES_EARLY.getCode().equals(followRemindType)) {
            followRemindTime = planFollowDate.minusMinutes(30);
        } else if (FollowRemindTypeEnum.ONE_HOUR_EARLY.getCode().equals(followRemindType)) {
            followRemindTime = planFollowDate.minusHours(1);
        } else if (FollowRemindTypeEnum.TWO_HOUR_EARLY.getCode().equals(followRemindType)) {
            followRemindTime = planFollowDate.minusHours(2);
        } else if (FollowRemindTypeEnum.ONE_DAY_EARLY.getCode().equals(followRemindType)) {
            followRemindTime = planFollowDate.minusDays(1);
        }
        return followRemindTime;
    }

    @Override
    public void asyncSendRemindInnerMsg(FollowPlan followPlan) {
        threadPoolTaskExecutor.execute(() -> sendRemindInnerMsg(followPlan));
    }

    @Override
    public boolean sendRemindInnerMsg(FollowPlan followPlan) {
        log.info("sendRemindMsg - 发送站内信提醒, followPlan={}", followPlan);
        String content = createRemindMsgContent(followPlan);
        if (StrUtil.isBlank(content)) {
            return false;
        }
        sendMsgUtil.sendInnerMsgByUserId(content, followPlan.getFollowUserId(), followPlan.getFollowRemindTime(), StaticContextUtil.getProjectSystemScene());
        return true;
    }

    @Override
    public void asyncSendRemindSmsMsg(FollowPlan followPlan) {
        threadPoolTaskExecutor.execute(() -> sendRemindSmsMsg(followPlan));
    }

    @Override
    public boolean sendRemindSmsMsg(FollowPlan followPlan) {
        log.info("sendRemindSmsMsg - 发送短信提醒, followPlan={}", followPlan);
        String content = createRemindMsgContent(followPlan);
        if (StrUtil.isBlank(content)) {
            return false;
        }
        SmsSendDTO smsSendDTO = new SmsSendDTO();
        smsSendDTO.setBusinessType(BusinessConstant.BUSINESS_COMMON);
        smsSendDTO.setChannelType(ChannelType.SMS);
        smsSendDTO.setBusinessId(ContextUtil.getTrace());
        smsSendDTO.setSystemScene(StaticContextUtil.getProjectSystemScene());
        // 封装内容
        Map<String, Object> contentMap = new HashMap<>(16);
        contentMap.put("content", content);
        SmsContentModel smsContentModel = new SmsContentModel();
        smsContentModel.setContentMap(contentMap);
        smsSendDTO.setSmsContentModelList(Collections.singletonList(smsContentModel));
        // 发送用户的手机号
        Set<String> mobileSet = new HashSet<>();
        Long followUserId = followPlan.getFollowUserId();
        UserAccountVo user = venueBookingUserAccountService.findSimpleById(followUserId);
        mobileSet.add(user.getMobile());
        smsSendDTO.setMobileList(mobileSet);
        // 发送时间
        smsSendDTO.setIsSendNow(BusinessConstant.NO);
        smsSendDTO.setPredictSendTime(followPlan.getFollowRemindTime());
        // 发送短信
        venueBookingMsgService.sendSmsMsg(smsSendDTO);
        return true;
    }

    private String createRemindMsgContent(FollowPlan  followPlan) {
        String subjectType = followPlan.getSubjectType();
        Long subjectId = followPlan.getSubjectId();
        if (StrUtil.isBlank(subjectType) || subjectId == null) {
            return null;
        }
        // 封装跟进内容
        String content = null;
        if (FollowPlanSubjectType.CUSTOMER_MAIN.getCode().equals(subjectType)) {
            CustomerMain customer = customerMainService.getById(subjectId);
            if (customer != null) {
                content = String.format(BusinessInnerMsgTemplate.FOLLOW_PLAN_TEMPLATE, "客户", customer.getCustomerCnName(), followPlan.getContent());
            }
        } else if (FollowPlanSubjectType.SALE_CLUE.getCode().equals(subjectType)) {
            SaleClue saleClue = saleClueService.getById(subjectId);
            if (saleClue != null) {
                content = String.format(BusinessInnerMsgTemplate.FOLLOW_PLAN_TEMPLATE, "线索", saleClue.getClueTitle(), followPlan.getContent());
            }
        } else if (FollowPlanSubjectType.BUSINESS_OPPORTUNITY.getCode().equals(subjectType)) {
            BusinessOpportunity businessOpportunity = businessOpportunityService.getById(subjectId);
            if (businessOpportunity != null) {
                content = String.format(BusinessInnerMsgTemplate.FOLLOW_PLAN_TEMPLATE, "商机", businessOpportunity.getBusinessTitle(), followPlan.getContent());
            }
        } else if (FollowPlanSubjectType.CONTRACT_MANAGE.getCode().equals(subjectType)) {
            ContractManage contractManage = contractManageService.getById(subjectId);
            if (contractManage != null) {
                content = String.format(BusinessInnerMsgTemplate.FOLLOW_PLAN_TEMPLATE, "合同", contractManage.getContractName(), followPlan.getContent());
            }
        } else {
            throw BizException.validFail("跟进记录类型参数错误");
        }
        return content;
    }
}
